//
//  UIImage+Tint.m
//  Battle
//
//  Created by YinDongbing on 16/6/11.
//  Copyright © 2016年 lepin. All rights reserved.
//

#import "UIImage+Tint.h"

@implementation UIImage (Tint)

- (UIImage *)imageWithCustomTintColor:(UIColor *)tintColor{
    if (@available(iOS 13.0, *)) {
        return [self imageWithTintColor:tintColor];
    }
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
    [tintColor setFill];
    CGRect bounds = CGRectMake(0.0f, 0.0f, self.size.width, self.size.height);
    UIRectFill(bounds);
    //Draw the tinted image in context
    [self drawInRect:bounds blendMode:kCGBlendModeDestinationIn alpha:1.0f];
    UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return tintedImage;
}

- (UIImage *)scaleWithFixedWidth:(CGFloat)width {
    
    float newHeight = self.size.height * (width / self.size.width);
    CGSize size     = CGSizeMake(width, newHeight);
    UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextTranslateCTM(context, 0.0, size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    CGContextSetBlendMode(context, kCGBlendModeCopy);
    CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, size.width, size.height), self.CGImage);
    
    UIImage *imageOut = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return imageOut;
}

/**
 压图片质量
 
 @param image image
 @param maxSize 最大质量大小 kb单位
 @return Data
 */
+ (NSData *)compressionimage:(UIImage *)image maxSize:(CGFloat)maxSize
{
    if (!image) {
        return nil;
    }
    CGFloat maxFileSize = maxSize*1024;
    CGFloat compression = 0.9f;
    NSData *compressedData = UIImageJPEGRepresentation(image, compression);
    while ([compressedData length] > maxFileSize) {
        compression *= 0.9;
        compressedData = UIImageJPEGRepresentation([[self class] compressImage:image newWidth:image.size.width*compression], compression);
    }
    return compressedData;
}
/**
 *  等比缩放本图片大小
 *
 *  @param newImageWidth 缩放后图片宽度，像素为单位
 *
 *  @return self-->(image)
 */
+ (UIImage *)compressImage:(UIImage *)image newWidth:(CGFloat)newImageWidth
{
    if (!image) return nil;
    float imageWidth = image.size.width;
    float imageHeight = image.size.height;
    float width = newImageWidth;
    float height = image.size.height/(image.size.width/width);
    
    float widthScale = imageWidth /width;
    float heightScale = imageHeight /height;
    
    // 创建一个bitmap的context
    // 并把它设置成为当前正在使用的context
    UIGraphicsBeginImageContext(CGSizeMake(width, height));
    
    if (widthScale > heightScale) {
        [image drawInRect:CGRectMake(0, 0, imageWidth /heightScale , height)];
    }
    else {
        [image drawInRect:CGRectMake(0, 0, width , imageHeight /widthScale)];
    }
    
    // 从当前context中创建一个改变大小后的图片
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    // 使当前的context出堆栈
    UIGraphicsEndImageContext();
    
    return newImage;
    
}

+ (UIImage *)screenshotsWithFrame:(CGRect)frame
{
    UIView *screenWindow =[UIApplication sharedApplication].keyWindow;
    CGFloat scale = [UIScreen mainScreen].scale;
    CGSize size = CGSizeMake(screenWindow.frame.size.width * scale, screenWindow.frame.size.height * scale);
    UIGraphicsBeginImageContextWithOptions(size,NO,0.0);//全屏截图，包括window
    [screenWindow drawViewHierarchyInRect:screenWindow.bounds afterScreenUpdates:NO];
    UIImage *viewImage =UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    CGRect newFrame = CGRectMake(frame.origin.x * scale, frame.origin.y * scale, frame.size.width* scale, frame.size.height* scale);
    CGImageRef cgimg = CGImageCreateWithImageInRect([viewImage CGImage], newFrame);
    UIImage * imgeee = [UIImage imageWithCGImage:cgimg];
    CGImageRelease(cgimg);
    return imgeee;
}

+ (UIImage *)reSizeImage:(UIImage *)image toSize:(CGSize)reSize

{
    UIGraphicsBeginImageContextWithOptions(reSize, NO, [UIScreen mainScreen].scale);
    [image drawInRect:CGRectMake(0, 0, reSize.width, reSize.height)];
    UIImage *reSizeImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return reSizeImage;
    
}


#pragma mark - 去白边
- (UIImage *)clipWithImageRect:(CGRect)clipRect
{
    CGImageRef cgImage = CGImageCreateWithImageInRect(self.CGImage, clipRect);
    UIImage *newImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return newImage;
}

- (NSInteger)checkImageWhiteSide
{
    CGFloat yScale = 2;
    NSInteger startX = 0;
    NSInteger startY = self.size.height / yScale;
    NSInteger endX = self.size.width;
    
    CGContextRef cgctx = [self createARGBBitmapContextFromImage:self.CGImage];
    CGImageRef inImage = self.CGImage;
    if (cgctx == NULL) { return NO;  }
    
    size_t w = CGImageGetWidth(inImage);
    size_t h = CGImageGetHeight(inImage);
    CGRect rect = {{0,0},{w,h}};
    
    // Draw the image to the bitmap context. Once we draw, the memory
    // allocated for the context for rendering will then contain the
    // raw image data in the specified color space.
    CGContextDrawImage(cgctx, rect, inImage);
    
    // Now we can get a pointer to the image data associated with the bitmap
    // context.
    unsigned char* data = CGBitmapContextGetData (cgctx);
    
    while ([self isWhiteColorAtPoint:CGPointMake(startX, startY) data:data rect:rect]) {
        startX++;
        //刚好遇到白线的时候 就重新取y值 动态设定y值
        //起点超过图片的一半 就定义为白线
        if (startX >= self.size.width / yScale ) {
            break;
        }
    }
    
    while ([self isWhiteColorAtPoint:CGPointMake(endX, startY) data:data rect:rect]) {
        endX--;
        if (endX <= self.size.width / yScale) {
            break;
        }
    }
    
    NSInteger point = MIN(startX, (self.size.width - endX));
    
    CGFloat XstartX = self.size.width / yScale;
    CGFloat YStartY = 0;
    CGFloat YEndY = self.size.height - 1;
    while ([self isWhiteColorAtPoint:CGPointMake(XstartX, YStartY) data:data rect:rect]) {
        YStartY++;
        //刚好遇到白线的时候 就重新取y值 动态设定y值
        //起点超过图片的一半 就定义为白线
        if (YStartY >= self.size.height / yScale ) {
            break;
        }
    }
    
    while ([self isWhiteColorAtPoint:CGPointMake(XstartX, YEndY) data:data rect:rect]) {
        YEndY--;
        if (YEndY <= self.size.height / yScale) {
            break;
        }
    }
    
    point = MIN(point, MIN(YStartY, self.size.height - YEndY));
    
    // When finished, release the context
    CGContextRelease(cgctx);
    // Free image data memory for the context
    if (data) { free(data); }
    //        _ratio = image.size.height / (image.size.width - point * 2);
    //        self.originalImageSize = CGSizeMake(image.size.width - point * 2, image.size.height);
    
    return point;
}

- (BOOL)isWhiteColorAtPoint:(CGPoint)point data:(unsigned char*)data rect:(CGRect)rect{
    
    CGFloat w = CGRectGetWidth(rect);
    BOOL isWhite = NO;
    if (data != NULL) {
        //offset locates the pixel in the data from x,y.
        //4 for 4 bytes of data per pixel, w is width of one row of data.
        @try {
            int offset = 4*((w*round(point.y))+round(point.x));
            
            
//            int alpha =  data[offset];
            int red = data[offset+1];
            int green = data[offset+2];
            int blue = data[offset+3];
            if (red > 240 && green > 240 && blue > 240) {
                isWhite = YES;
            }
        }
        @catch (NSException * e) {
//            DLog(@"%@",[e reason]);
        }
        @finally {
        }
        
    }
    
    return isWhite;
}


//FIXME: CGContextRef 上下文不应该通过函数返回
- (CGContextRef) createARGBBitmapContextFromImage:(CGImageRef) inImage {
    
    CGContextRef    context = NULL;
    CGColorSpaceRef colorSpace;
    void *          bitmapData;
    int             bitmapByteCount;
    int             bitmapBytesPerRow;
    
    // Get image width, height. We'll use the entire image.
    size_t pixelsWide = CGImageGetWidth(inImage);
    size_t pixelsHigh = CGImageGetHeight(inImage);
    
    // Declare the number of bytes per row. Each pixel in the bitmap in this
    // example is represented by 4 bytes; 8 bits each of red, green, blue, and
    // alpha.
    bitmapBytesPerRow   = (int)(pixelsWide * 4);
    bitmapByteCount     = (int)(bitmapBytesPerRow * pixelsHigh);
    
    // Use the generic RGB color space.
    colorSpace = CGColorSpaceCreateDeviceRGB();
    
    if (colorSpace == NULL)
    {
        CGColorSpaceRelease(colorSpace);
        fprintf(stderr, "Error allocating color space\n");
        return NULL;
    }
    
    // Allocate memory for image data. This is the destination in memory
    // where any drawing to the bitmap context will be rendered.
    bitmapData = malloc( bitmapByteCount );
    if (bitmapData == NULL)
    {
        fprintf (stderr, "Memory not allocated!");
        CGColorSpaceRelease(colorSpace);
        return NULL;
    }
    
    // Create the bitmap context. We want pre-multiplied ARGB, 8-bits
    // per component. Regardless of what the source image format is
    // (CMYK, Grayscale, and so on) it will be converted over to the format
    // specified here by CGBitmapContextCreate.
    context = CGBitmapContextCreate (bitmapData,
                                     pixelsWide,
                                     pixelsHigh,
                                     8,      // bits per component
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedFirst);
    if (context == NULL)
    {
        free (bitmapData);
        CGColorSpaceRelease(colorSpace);
        fprintf (stderr, "Context not created!");
        return NULL;
    }
    // Make sure and release colorspace before returning
    CGColorSpaceRelease( colorSpace );
    
    return context;
}

//按比例缩放,size 是你要把图显示到 多大区域
+ (UIImage *) imageCompressFitSizeScale:(UIImage *)sourceImage targetSize:(CGSize)size{
    UIImage *newImage = nil;
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = size.width;
    CGFloat targetHeight = size.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0, 0.0);
    
    if(CGSizeEqualToSize(imageSize, size) == NO){
        
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;
        
        if(widthFactor > heightFactor){
            scaleFactor = widthFactor;
            
        }
        else{
            
            scaleFactor = heightFactor;
        }
        scaledWidth = width * scaleFactor;
        scaledHeight = height * scaleFactor;
        
        if(widthFactor > heightFactor){
            
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }else if(widthFactor < heightFactor){
            
            thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
        }
    }
    
    UIGraphicsBeginImageContext(size);
    
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    
    [sourceImage drawInRect:thumbnailRect];
    
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil){
//        DLog(@"scale image fail");
    }
    
    UIGraphicsEndImageContext();
    return newImage;
}

- (UIImage *)normalizedImage:(UIImage *)image{
    if (image.imageOrientation == UIImageOrientationUp) return image;
    UIGraphicsBeginImageContextWithOptions(image.size, NO, 1);
    [image drawInRect:(CGRect){0, 0, image.size}];
    UIImage *normalizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return normalizedImage;
}

@end
